package com.mark.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mark.common.Const;
import com.mark.common.ServerResponse;
import com.mark.dao.CategoryMapper;
import com.mark.exception.CategoryException;
import com.mark.pojo.Category;
import com.mark.service.ICategoryService;
import com.mark.util.JsonUtil;
import com.mark.util.RedisShardedPoolUtil;
import com.mark.vo.CategoryVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;

/**
 * Created by Mark on 2018/3/24.
 * 商品种类模块Service层业务逻辑
 */
@Service("iCategoryService")
@Slf4j
public class CategoryServiceImpl implements ICategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    //1.添加非一级商品种类
    @Override
    public ServerResponse addCategory(String categoryName, Integer parentId, String imageAddress) {
        try {
            Category category = new Category();
            category.setProductCategoryName(categoryName);
            category.setParentId(parentId);
            category.setEnableStatus(true);
            category.setImageAddress(imageAddress);
            category.setPriority(1);
            int rowCount = categoryMapper.insert(category);//插入数据
            if (rowCount > 0) {
                String redisToken = "categoryList" + parentId;
                RedisShardedPoolUtil.del(redisToken);//删除Redis中的对应缓存
                return ServerResponse.createBySuccess("添加商品种类成功");
            }
            return ServerResponse.createByErrorMessage("添加商品种类失败");
        }catch (Exception e){
            throw new CategoryException("addCategory",e.getClass()+e.getMessage());
        }
    }

    //2.更新商品种类名称
    @Override
    public ServerResponse updateCategoryName(Integer categoryId, String categoryNewName) {
        try {
            Category categoryNew = new Category();
            categoryNew.setId(categoryId);
            categoryNew.setProductCategoryName(categoryNewName);
            int rowCount = categoryMapper.updateByPrimaryKeySelective(categoryNew);
            if (rowCount > 0) {
                String redisToken = "category" + categoryId;
                RedisShardedPoolUtil.del(redisToken);//如果是更新操作从redis中删除，保证Redis缓存中存放的是最新的数据
                Category category = categoryMapper.selectByPrimaryKey(categoryId);
                RedisShardedPoolUtil.del("categoryList" + category.getParentId());
                return ServerResponse.createBySuccess("更新品类名字成功");
            }
            return ServerResponse.createByErrorMessage("更新品类名字失败");
        }catch (Exception e){
            throw new CategoryException("updateCategoryName",e.getClass()+e.getMessage());
        }
    }

    //3.查找有相同父结点的结点
    @Override
    public ServerResponse<List<CategoryVo>> getChildrenParallelCategory(Integer categoryId) {
        try {
            List<Category> categoryList = Lists.newArrayList();
            String redisToken = "categoryList" + categoryId;
            String categoryListJsonStr = RedisShardedPoolUtil.get(redisToken);//从Redis取值
            if (categoryListJsonStr != null) {
                categoryList = JsonUtil.string2Obj(categoryListJsonStr, List.class, Category.class);
                log.info("正在从Redis缓存中取【categoryList】数据");
            } else {
                categoryList = categoryMapper.selectCategoryChildrenByParentId(categoryId);
                RedisShardedPoolUtil.set(redisToken, JsonUtil.obj2String(categoryList));//缓存到Redis
            }
            if (CollectionUtils.isEmpty(categoryList)) {
                log.info("未找到当前分类的子分类");
            }
            List<CategoryVo> categoryVoList = Lists.newArrayList();
            for (Category category : categoryList) {
                CategoryVo categoryVo = new CategoryVo();
                categoryVo = categoryVo.assembleCategoryVo(category);
                categoryVoList.add(categoryVo);
            }
            return ServerResponse.createBySuccess(categoryVoList);
        }catch (Exception e){
            throw new CategoryException("getChildrenParallelCategory",e.getClass()+e.getMessage());
        }
    }

    //4.递归查询本节点的id及孩子节点的id
    @Override
    public ServerResponse<List<Integer>> selectCategoryAndChildrenById(Integer categoryId) {
        try {

            Set<Category> categorySet = Sets.newHashSet();
            findChildCategory(categorySet,categoryId);
            List<Integer> categoryIdList = Lists.newArrayList();
            for(Category category : categorySet){
                categoryIdList.add(category.getId());
            }
            return ServerResponse.createBySuccess(categoryIdList);
        }catch (Exception e){
            throw new CategoryException("selectCategoryAndChildrenById",e.getClass()+e.getMessage());
        }
    }

    @Override
    public Category selectCategoryById(Integer id) {
        try{
            String redisToken = "category"+id;
            String categoryJsonStr =  RedisShardedPoolUtil.get(redisToken);
            Category category = JsonUtil.string2Obj(categoryJsonStr,Category.class);//如果redis中存在就取redis中的值
            if(category != null){
                log.info("正在从Redis缓存中取【category"+id+"】数据");
                return category;
            }else{
                category = categoryMapper.selectByPrimaryKey(id);//保存到redis缓存
                RedisShardedPoolUtil.set(redisToken,JsonUtil.obj2String(category));
                return category;
            }
        }catch (Exception e){
            throw new CategoryException("selectCategoryById",e.getClass()+e.getMessage());
        }
    }

    //递归函数,算出子节点
    private Set<Category> findChildCategory(Set<Category> categorySet, Integer categoryId) {
        try {
            String redisToken = "category" + categoryId;
            String categoryJsonStr = RedisShardedPoolUtil.get(redisToken);
            Category category = JsonUtil.string2Obj(categoryJsonStr, Category.class);//如果redis中存在就取redis中的值
            if (category != null) {
                log.info("正在从Redis缓存中取【category" + categoryId + "】数据");
            } else {
                category = categoryMapper.selectByPrimaryKey(categoryId);
                RedisShardedPoolUtil.set(redisToken, JsonUtil.obj2String(category));
            }
            if (category != null) {
                categorySet.add(category);
            }
            //查找子节点,递归算法一定要有一个退出的条件
            Integer parentId = categoryId;
            List<Category> categoryList = categoryMapper.selectCategoryChildrenByParentId(parentId);
            for (Category categoryItem : categoryList) {
                findChildCategory(categorySet, categoryItem.getId());
            }
            return categorySet;
        }catch (Exception e){
            throw new CategoryException("findChildCategory",e.getClass()+e.getMessage());
        }
    }
}
